<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>this、call、apply、bind</title>
</head>
<body>
  <h3>打开控制台</h3>

  <script>
    // // 纯粹的函数调用：属于全局性调用，因此this就代表全局对象
    // var name = 'monster';
    // function hi(){
    //   console.log(this.name);
    // }
    // hi(); // monster

    // // 作为对象方法的调用：函数还可以作为某个对象的方法调用，此时this就指这个上级对象
    // var obj = {};
    // obj.name = 'lzx';
    // obj.sayHi = hi;
    // obj.sayHi(); // lzx
    // hi(); // monster

    // // 作为构造函数调用：所谓构造函数，就是通过这个函数，可以生成一个新对象。此时，this就指这个新对象
    // function newHi() {
    //   this.name = 'six';
    // }
    // var l = new newHi();
    // console.log(name); // monster
    // console.log(l.name); // six

    // call、apply、bind
    var name = 'monster'
    var obj = {
      name: 'lzx',
      age: 22,
    }
    function getName(name) {
      console.log(this.name, name);
    }
    // getName(); // monster undefined
    // getName.call(); // monster undefined
    // getName.call(obj); // lzx undefined
    // getName.call(obj, 'six'); // lzx six

    // getName.apply(); // monster undefined
    // getName.apply(obj); // lzx undefined
    // // getName.apply(obj, 'six'); // Uncaught TypeError: CreateListFromArrayLike called on non-object
    // getName.apply(obj, ['six']); // lzx six

    // getName.bind(); // 什么都没有
    // getName.bind()(); // monster undefined
    // getName.bind(obj)(); // lzx undefined
    // getName.bind(obj, 'six')(); // lzx six
    // getName.bind(obj)('six'); // lzx six
    // getName.bind(obj, ['six'])(); // lzx ['six']

    // 自定义bind
    function myBind(fn, context) {
      return function() {
        return fn.apply(context, arguments);
      }
    }
    const l = myBind(getName, obj);
    l('six'); // lzx six

  </script>
</body>
</html>